<template>
  <div class="draggable-container">
    <!-- 顶部操作 -->
    <div class="controls">
      <button @click="openComponentLibrary" class="control-btn add-component-library">选择组件库</button>
      <button @click="save" class="control-btn">保存</button>
    </div>

    <!-- 栅格区域 -->
    <div class="grid-container">
      <div class="grid-background" ref="gridContainer">
        <div
                v-for="i in gridColumns * gridRows"
                :key="i"
                class="grid-cell"
        ></div>
      </div>

      <!-- 拖拽区域 -->
      <div class="draggable-area">
        <div
                v-if="snapGuide.x.show"
                class="snap-guide snap-guide-x"
                :style="{ left: snapGuide.x.pos + 'px' }"
        ></div>
        <div
                v-if="snapGuide.y.show"
                class="snap-guide snap-guide-y"
                :style="{ top: snapGuide.y.pos + 'px' }"
        ></div>

        <!-- 动态组件 -->
        <Vue3DraggableResizable
                v-for="(item, index) in components"
                :key="item.id + '-' + (item.version || 0)"
                v-model:x="item.x"
                v-model:y="item.y"
                v-model:w="item.width"
                v-model:h="item.height"
                :initW="item.width"
                :initH="item.height"
                :minW="gridCellWidth"
                :minH="gridCellHeight"
                :active="item.id === selectedId"
                :parent="true"
                :disabledY="false"
                :handles="['br']"
                :drag-options="{ preventDefaultOnMove: true }"
                @drag-start="onDragStart(item.id, index)"
                @drag-end="() => onDragEnd(index)"
                @dragging="() => onDraging(index)"
                @resize-start="onResizeStart(item.id)"
                @resize-end="(rect) => onResizeEnd(index, rect)"
                @resizing="(rect) => onResizing(index, rect)"
                @click="selectComponent(item.id, $event)"
        >
          <RenderEngine
                  :item="item"
                  :selected-id="selectedId"
                  @delete="handleDeleteComponent"
          />
        </Vue3DraggableResizable>
      </div>
    </div>

    <!-- 左侧抽屉：组件库 -->
    <t-drawer
            title="组件库"
            :visible="isDrawerVisible"
            placement="left"
            @close="isDrawerVisible = false"
            :width="360"
    >
      <div class="component-library">
        <div class="component-item" @click="addComponent('轮播图', 'swiper')">轮播图</div>
        <div class="component-item" @click="addComponent('新闻动态', 'news')">新闻动态</div>
        <div class="component-item" @click="addComponent('商品', 'commodity')">商品</div>
        <div class="component-item" @click="addComponent('菜单', 'menus')">菜单</div>
      </div>
    </t-drawer>
  </div>
</template>

<script setup>
  import { ref, onMounted, onUnmounted, nextTick } from 'vue';
  import Vue3DraggableResizable from 'vue3-draggable-resizable';
  import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css';
  import RenderEngine from '../components/RenderEngine2.vue';
  import PageService from '../api/page';
  import { useDraggableGrid } from '../composables/useDraggableGrid';
  import { useRoute } from 'vue-router';
  const route = useRoute();

  // ---------------------------
  // 基础配置与响应式状态
  // ---------------------------
  const pageInfo = ref({});
  const components = ref([]);
  const gridContainer = ref(null);
  const isDrawerVisible = ref(false);

  // 栅格配置
  const gridColumns = 12;
  const gridRows = 12;
  const gridGap = ref(10);
  const gridCellWidth = ref(0);
  const gridCellHeight = ref(0);

  // 拖拽缩放逻辑封装
  const {
    selectedId,
    snapGuide,
    selectComponent,
    onDragStart,
    onDraging,
    onDragEnd,
    onResizeStart,
    onResizing,
    onResizeEnd
  } = useDraggableGrid(components, gridContainer, {
    gridCellWidth,
    gridCellHeight,
    gridGap
  });

  // UI交互
  const openComponentLibrary = () => {
    isDrawerVisible.value = true;
  };

  // 计算栅格尺寸
  const updateGridSize = () => {
    const container = gridContainer.value;
    if (!container) return;

    const containerWidth = container.clientWidth;
    gridCellWidth.value = Math.round((containerWidth - (gridColumns - 1) * gridGap.value) / gridColumns);
    // 固定比例计算高度
    gridCellHeight.value = Math.round(gridCellWidth.value * (90 / 146.5));
  };

  const generateId = () => Math.floor(Math.random() * 10000) + Date.now();

  const checkCollision = (a, b) => {
    const tolerance = 1; // 1px 容差
    return !(
            a.x + a.width <= b.x + tolerance ||
            a.x >= b.x + b.width - tolerance ||
            a.y + a.height <= b.y + tolerance ||
            a.y >= b.y + b.height - tolerance
    );
  };

  const addComponent = (title, type) => {
    if (!gridContainer.value || gridCellWidth.value === 0) return;

    // 1. 定义新组件的尺寸 (基于 4x4 栅格)
    const width = gridCellWidth.value * 4 + gridGap.value * 3;
    const height = gridCellHeight.value * 4 + gridGap.value * 3;

    // 2. 定义栅格步长和画布边界
    const containerWidth = gridContainer.value.clientWidth;
    const stepX = gridCellWidth.value + gridGap.value;
    const stepY = gridCellHeight.value + gridGap.value;
    const offset = gridGap.value;

    let finalX = offset;
    let finalY = offset;
    let foundSlot = false;

    // 3. 查找优先空位 (Find First Fit) 算法
    // 逐行 (y) 扫描
    for (let y = offset; y < 9999; y += stepY) {
      // 逐列 (x) 扫描
      for (let x = offset; x <= containerWidth - width + offset; x += stepX) {

        // 4. 创建候选位置
        const candidate = { x, y, width, height };

        // 5. 检查候选位置是否与现有组件重叠
        const isOccupied = components.value.some(comp => checkCollision(candidate, comp));

        if (!isOccupied) {
          // 6. 找到空位
          finalX = x;
          finalY = y;
          foundSlot = true;
          break;
        }
      }
      if (foundSlot) break;
    }

    // 7. 创建并添加新组件
    const newComponent = {
      id: generateId(),
      title,
      type,
      x: finalX,
      y: finalY,
      width,
      height,
      xEnd: finalX + width,
      yEnd: finalY + height,
      slides: type === 'swiper' ? [] : ''
    };

    components.value.push(newComponent);
    selectedId.value = newComponent.id;
    isDrawerVisible.value = false;
  };

  // ---------------------------
  // 删除组件
  // ---------------------------
  const handleDeleteComponent = (id, e) => {
    e?.stopPropagation?.();
    if (window.confirm && !window.confirm('确定删除该组件吗？')) return;

    components.value = components.value.filter(item => item.id !== id);
    if (selectedId.value === id) selectedId.value = null;
  };

  // ---------------------------
  // 页面加载与保存
  // ---------------------------
  const getPage = async (id) => {
    try {
      const { data } = await PageService.getPageById(id);
      console.log(data)
      pageInfo.value = data;
      if (data) {
        const schema = JSON.parse(data.schemaJson || '{}');
        if (schema.page?.components?.length) {
          await nextTick();
          components.value = parseTemplateToComponents(schema.page.components, gridContainer);
        }
      }
    } catch (e) {
      console.error('获取页面失败:', e);
    }
  };

  const save = async () => {
    const container = gridContainer.value;
    if (!container) {
      console.error('容器不存在，无法保存布局');
      return;
    }
    const containerWidth = container.clientWidth;
    const containerHeight = container.clientHeight;
    const componentDto = transformComponentsToTemplate(components.value, containerWidth, containerHeight);
    try {
      const pageDto = {
        schemaJson : JSON.stringify(componentDto)
      }
      await PageService.updatePage(pageInfo.value.id, pageDto);
      alert('保存成功！');
    } catch (e) {
      console.error('保存失败:', e);
    }
  };

  // 模板解析
  function parseTemplateToComponents(componentList, gridContainer) {
    const container = gridContainer.value;
    if (!container) {
      console.error('容器不存在');
      return [];
    }

    const containerWidth = container.clientWidth;
    const containerHeight = container.clientHeight;

    return componentList.map(comp => {
      const layout = comp.layout || comp;
      const scale = (val, total) => (val / 100) * total;

      return {
        id: comp.id,
        title: comp.title,
        type: comp.type,
        x: scale(layout.x, containerWidth),
        y: scale(layout.y, containerHeight),
        width: scale(layout.width, containerWidth),
        height: scale(layout.height, containerHeight),
        layout
      };
    });
  }

  function transformComponentsToTemplate(components, containerWidth, containerHeight) {
    return {
      page: {
        id: "home", // 页面唯一ID
        title: "首页模板",
        layout: {
          grid: {
            columns: 12,
            gap: 10
          }
        },
        components: components.map(comp => {
          // 计算百分比
          const xPercent = ((comp.x / containerWidth) * 100).toFixed(4);
          const yPercent = ((comp.y / containerHeight) * 100).toFixed(4);
          const widthPercent = ((comp.width / containerWidth) * 100).toFixed(4);
          const heightPercent = ((comp.height / containerHeight) * 100).toFixed(4);

          return {
            id: String(comp.id),
            title: comp.title,
            type: comp.type,
            layout: {
              x: parseFloat(xPercent),
              y: parseFloat(yPercent),
              width: parseFloat(widthPercent),
              height: parseFloat(heightPercent)
            }
          }
        })
      }
    }
  }

  // 生命周期
  onMounted(() => {
    updateGridSize();
    window.addEventListener('resize', updateGridSize);
    // 从路由获取 id 参数
    const id = route.query.id || route.params.id;
    if (id) {
      getPage(id);
    } else {
      console.warn("未获取到页面ID，无法加载页面");
    }
  });

  onUnmounted(() => {
    window.removeEventListener('resize', updateGridSize);
  });
</script>

<style scoped src="../style/web.css"></style>
